﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Checkers.Sever.DBModule.databaseProxy;
using Checkers.Sever.DBModule;
using Checkers.Service.WCFService.databaseProxyDataContract;

namespace Checkers.Service.WCFService
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "GameRoomService" in code, svc and config file together.
    public class GameRoomService : IGameRoomService
    {
        public IDatabaseUtility IDBUtil;

        public GameRoomService()
        {
            IDBUtil = clsDatabaseUtility.getInstance();
        }

        public databaseProxyDataContract.clsGameRoom CreateGameRoom(databaseProxyDataContract.clsPlayer objClsPlayer)
        {
            var objGameRoom = IDBUtil.CreateGameRoom(objClsPlayer.PlayerId);

            var objClsGameRoom = new databaseProxyDataContract.clsGameRoom()
            {
                GameId = objGameRoom.gameId,
                GameStatus = objGameRoom.gameStatus,
                IsOccupiedStatus = objGameRoom.isOccupiedBy
            };
            return objClsGameRoom;
        }


        public IList<databaseProxyDataContract.clsGameRoom> GetGameRoomList()
        {
            var gameList = IDBUtil.GetGameRooms();
            var gameClsList = new List<clsGameRoom>();

            foreach(GameRoom room in gameList)
            {
                var clsRoom = new clsGameRoom() 
                {
                    GameId = room.gameId,
                    GameStatus = room.gameStatus,
                    Timestamp = room.timestamp,
                    IsOccupiedStatus = room.isOccupiedBy
                };

                gameClsList.Add(clsRoom);
                
            }

            return gameClsList;
        }


        public clsGameRoom JoinGameRoom(clsPlayer objClsPlayer, clsGameRoom objClsGameRoom)
        {
            var gameRoomClientList = IDBUtil.GetGameRoomSubscribers(objClsGameRoom.GameId);
            
            /*
            check if user is already a subsriber of the game room if yes then do nothing else add him as a player or viewer
             */
            foreach(GameRoomClient roomClient in gameRoomClientList)
            {
                if (roomClient.playerId == objClsPlayer.PlayerId) 
                {
                    return objClsGameRoom;
                }
            }

            if (gameRoomClientList.Count == 1)
            {
                /*
                 add the player entry in game room suscriber table
                 */
                var objGameRoom1 = IDBUtil.JoinGameRoom(objClsPlayer.PlayerId, objClsGameRoom.GameId, 1);
                /*
                 * update the gameroom table status to viewonly
                 * 
                 */
                var objGameRoom2 = IDBUtil.UpdateGameRoomStatus(objClsGameRoom.GameId, 1);

                
            }
            else 
            {
                /*
                 add the player entry in game room suscriber table
                 */
                var objGameRoom1 = IDBUtil.JoinGameRoom(objClsPlayer.PlayerId, objClsGameRoom.GameId, 2);
                

            }

            return objClsGameRoom;
            
        }


        public IList<clsGameMoves> GetAllMoves(clsGameRoom objClsGameRoom)
        {
            var gameMoveList = IDBUtil.GetGameMovesSortedByTimeStamp(objClsGameRoom.GameId);
            var clsGameMoveList = new List<clsGameMoves>();

            foreach(GameMove move in gameMoveList)
            {
                var clsObjPlayer = new clsPlayer()
                {
                    PlayerId = move.Player.playerId,
                    PlayerName = move.Player.playerName,
                    PlayerUserName = move.Player.playerUsername,
                    PlayerPassword = move.Player.playerPassword
                };
                var clsObjGameRoom = new clsGameRoom()
                {
                    GameId = move.GameRoom.gameId,
                    GameStatus = move.GameRoom.gameStatus,
                    Timestamp = move.GameRoom.timestamp,
                    IsOccupiedStatus = move.GameRoom.isOccupiedBy
                };

                var obj = new clsGameMoves() 
                {
                    MoveId = move.moveId,
                    GameRoom = clsObjGameRoom,
                    Player = clsObjPlayer,
                    PieceId = move.pieceId,
                    FinalPositionPanelId = move.finalPositionPanelId,
                    Timestamp = move.timestamp,
                    ListOfRemovedPieces = move.listOfRemovedPieces,
                    IsKing = move.isKing
                };

                clsGameMoveList.Add(obj);
            }

            return clsGameMoveList;
        }


        public IList<clsGameRoomClient> GetAllViewers(clsGameRoom gameRoom)
        {
            var gameRoomClientList = IDBUtil.GetGameRoomSubscribers(gameRoom.GameId);
            var clsGameRoomClientList = new List<clsGameRoomClient>();

            foreach(GameRoomClient client in gameRoomClientList)
            {
                var clsObjPlayer = new clsPlayer()
                {
                    PlayerId = client.Player.playerId,
                    PlayerName = client.Player.playerName,
                    PlayerUserName = client.Player.playerUsername,
                    PlayerPassword = client.Player.playerPassword
                };
                var clsObjGameRoom = new clsGameRoom()
                {
                    GameId = client.GameRoom.gameId,
                    GameStatus = client.GameRoom.gameStatus,
                    Timestamp = client.GameRoom.timestamp,
                    IsOccupiedStatus = client.GameRoom.isOccupiedBy
                };

                var obj = new clsGameRoomClient() 
                {
                    Id = client.id,
                    GameRoom = clsObjGameRoom,
                    Player = clsObjPlayer,
                    PlayerType = client.playerType
                };
                clsGameRoomClientList.Add(obj);
            }

            return clsGameRoomClientList;
        }




        public void AddMove(clsGameMoves gameMove)
        {
            var gameMoveObj = IDBUtil.AddMove(gameMove.Player.PlayerId,gameMove.GameRoom.GameId,
                gameMove.PieceId,gameMove.FinalPositionPanelId,gameMove.Timestamp,gameMove.ListOfRemovedPieces, gameMove.IsKing);
        }

        

        public void UpdateGameRoomOccupiedStatus(clsGameRoom gameRoom)
        {
            var status = 0;

            if(gameRoom.IsOccupiedStatus == 0)
            {
                status = 1;
            }
            else
            {
                status = 0;
            }
            var objGameRoom = IDBUtil.UpdateOccupiedStatusOfGameRoom(gameRoom.GameId, status);
           
        }

        public clsWinner CheckForWinner(clsGameRoom gameRoom, clsPlayer player) 
        {
            var winner = IDBUtil.GetWinner(gameRoom.GameId);
            

            if(winner == null)
            {
                var gameMovesList = IDBUtil.CheckForWinnerStatus(gameRoom.GameId);

                Console.WriteLine(gameMovesList.Count());

                if (gameMovesList.Count() < 12)
                {
                    return null;
                }

                int count_red = 0;
                int count_yellow = 0;

                foreach (GameMove move in gameMovesList)
                {
                    var pieceTypeRemoved = move.listOfRemovedPieces;
                    var pieceType = getPieceType(pieceTypeRemoved);
                    if (pieceType == 0)
                    {
                        //yellow
                        count_yellow++;
                    }
                    else if(pieceType == 1)
                    {
                        count_red++;
                    }
                }


                if (count_yellow == 12)
                {
                    //yellow wins
                    var objWinner = IDBUtil.AddWinnerToGame(gameRoom.GameId, player.PlayerId);
                    var objClsWinner = new clsWinner() 
                    {
                        GameWinnerId = objWinner.gameWinnerId,
                        Player = player,
                        GameRoom = gameRoom
                    };
                    return objClsWinner;
                }

                if (count_red == 12)
                {
                    var objWinner = IDBUtil.AddWinnerToGame(gameRoom.GameId, player.PlayerId);
                    var objClsWinner = new clsWinner()
                    {
                        GameWinnerId = objWinner.gameWinnerId,
                        Player = player,
                        GameRoom = gameRoom
                    };
                    return objClsWinner;
                }

                return null;
            }

            var objClsPlayer = new clsPlayer()
            {
                PlayerId = winner.Player.playerId,
                PlayerName = winner.Player.playerName,
                PlayerPassword = winner.Player.playerPassword,
                PlayerUserName = winner.Player.playerUsername
            };

            var objClsGameRoom = new clsGameRoom() 
            {
                GameId = winner.GameRoom.gameId,
                GameStatus = winner.GameRoom.gameStatus
            };

            var objClsWinnerFound = new clsWinner()
            {
                GameWinnerId = winner.gameWinnerId,
                Player = objClsPlayer,
                GameRoom = objClsGameRoom
            };

            return objClsWinnerFound;
        }

        private int getPieceType(string pieceTypeRemoved)
        {
            string[] splitStrArr = pieceTypeRemoved.Split('_');

            if (splitStrArr[1] == "0")
            {
                return 0;
            }
            else if (splitStrArr[1] == "1")
            {
                return 1;
            }

            throw new Exception("Invalid Piece Type");
        }


    }


    
}
